package com.zwb.demo.eventlistener;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;

/**
 * 事件发布器
 *
 * @author zwb
 */
public class EventPublisher {

    /**
     * 监听者容器, 事件类型->监听者集合
     */
    private Map<Class<?>, Set<Object>> listeners = new HashMap<>();

    /**
     * 注册一个监听者
     *
     * @param o 监听者
     */
    public void register(Object o) {
        Class<?>[] interfaces = o.getClass().getInterfaces();
        for (Class<?> anInterface : interfaces) {
            if (EventListener.class.isAssignableFrom(anInterface)) {
                Set<Object> set = listeners.computeIfAbsent(anInterface, k -> new HashSet<>());
                set.add(o);
            }
        }
    }

    /**
     * 发布一个事件
     *
     * @param clazz    事件类型字节码
     * @param consumer 行为
     * @param <T>      事件类型
     */
    @SuppressWarnings("unchecked")
    public <T> void publishEvent(Class<T> clazz, Consumer<T> consumer) {
        Set<Object> set = listeners.get(clazz);
        if (set != null) {
            for (Object o : set) {
                consumer.accept((T) o);
            }
        }

    }

    /**
     * 注册一个监听者
     *
     * @param clazz 监听类型
     * @param o     监听者
     */
    @Deprecated
    public void register(Class<? extends EventListener> clazz, EventListener o) {
        Set<Object> eventListeners = listeners.computeIfAbsent(clazz, k -> new HashSet<>());
        eventListeners.add(o);
    }
    //----------------------单例----------------------

    static enum Singleton {
        SINGLETON,
        ;
        private final EventPublisher publisher;

        Singleton() {
            publisher = new EventPublisher();
        }
    }

    /**
     * 获取单例
     *
     * @return 单例对象
     */
    public static EventPublisher getInstance() {
        return Singleton.SINGLETON.publisher;
    }
}
